#ifndef __INSTRUCTION_H__
#define __INSTRUCTION_H__

#include <stdint.h>
#include <stdbool.h>

/* Instruction decoding enums and structures for emulator and assembler */

enum reg { 
	R0	= 0,
	R1	= 1,
	R2	= 2,
	R3	= 3,
	R4	= 4,
	R5	= 5,
	PC	= 6,
	UPC	= 7,
}; 
 
enum carry { 
    CARRY_1 = 0, 
    CARRY_F = 1, 
}; 
 
enum flag { 
    FLAG_F			= 0, 
	FLAG_0			= 1,
	FLAG_C			= 2,
	FLAG_NOT_C		= 3,
	FLAG_Q4			= 4,
	FLAG_Q5			= 5,
	FLAG_Q6			= 6,
	FLAG_Q7			= 7,
}; 
 
enum op { 
	OP_NOP = 0,
	OP_AND = 1,
	OP_IOR = 2,
	OP_ADD = 3,
}; 
 
enum y { 
    Y_A     = 0, 
    Y_A_SHR = 1, 
    Y_B     = 2, 
    Y_NOT_B = 3 
}; 
 
enum x { 
    X_0     = 0, 
    X_A     = 1,
};

/*	Macros used for bitfields that must match in layout
	regardless of endianness. Members are listed from lsb
	to msb. */
#ifdef __LITTLE_ENDIAN__
/* gcc lays out lsb first */
#define BITFIELD(member, next) member; next
#else
/* gcc lays out msb first */
#define BITFIELD(member, next) next member;
#endif

union instruction { 
    int16_t i;   
    struct { 
		BITFIELD(enum op	o	: 2, //operation
		BITFIELD(enum flag	f	: 3, //flag write
		BITFIELD(enum y		y	: 2, //right alu in
		BITFIELD(enum x		x	: 1, //left alu in
		BITFIELD(bool		c	: 1, //carry in
		BITFIELD(bool		w	: 1, //write?
		BITFIELD(enum reg	b	: 3, //right reg
		BITFIELD(enum reg	a	: 3, //left reg
		))))))))
    } b;
    struct { 
		BITFIELD(int16_t	i	: 7, //immediate
		BITFIELD(int16_t		: 9, //use b field to decode
		))
    } u; 
}; 

#endif
